Add OpenVMM virtio device support - #4621
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds virtio device selection support for OpenVMM guests, allowing runbooks to choose virtio-blk disks and virtio-net NICs over PCIe while keeping the existing synthetic/SCSI defaults. This extends the OpenVMM launch command generation, updates the OpenVMM runbook schema to accept the new options, and adds selftests to validate command composition and runbook propagation.
Changes:
- Add
disk_deviceandnetwork_deviceoptions (with validation) and propagate them into OpenVMM launch configuration. - Extend OpenVMM command-line generation to emit PCIe + virtio device arguments when requested, while retaining current defaults.
- Add/extend selftests covering command output, schema loading, and launch propagation behavior.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| selftests/test_openvmm_tool.py | Validates default vs virtio+PCIe command-line generation in OpenVmm.build_command(). |
| selftests/test_openvmm_schema.py | Ensures OpenVMM guest schema accepts virtio device selections. |
| selftests/test_openvmm_node.py | Verifies launch config propagation for disk/network device selections. |
| lisa/tools/openvmm.py | Adds device-selection constants, launch config fields, validation, and virtio/PCIe argument composition. |
| lisa/sut_orchestrator/openvmm/schema.py | Adds disk_device and network.device schema fields with validation and defaults. |
| lisa/sut_orchestrator/openvmm/node.py | Propagates runbook device selections into OpenVmmLaunchConfig. |
AI Test Case SelectionSelected 2 test case(s): verify_boot_with_debug_kernel,verify_serial_console Marketplace image: Result: Failed |
1 similar comment
AI Test Case SelectionSelected 2 test case(s): verify_boot_with_debug_kernel,verify_serial_console Marketplace image: Result: Failed |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Suppressed comments (4)
lisa/tools/openvmm.py:156
- Error message doesn’t list the supported network device values, which makes it harder to fix invalid configurations. Consider including the supported values in the exception message (consistent with the schema validation errors).
raise LisaException(
f"Unsupported OpenVMM network device: {config.network_device}"
)
lisa/tools/openvmm.py:162
- Error message doesn’t list the supported IOMMU values, which makes it harder to fix invalid configurations. Consider including the supported values in the exception message (consistent with the schema validation errors).
raise LisaException(f"Unsupported OpenVMM IOMMU: {config.iommu}")
lisa/tools/openvmm.py:149
- Error message doesn’t list the supported disk device values, which makes it harder to fix invalid configurations. Consider including the supported values in the exception message (consistent with the schema validation errors).
This issue also appears in the following locations of the same file:
- line 154
- line 162
raise LisaException(
f"Unsupported OpenVMM disk device: {config.disk_device}"
)
lisa/sut_orchestrator/openvmm/schema.py:113
- This PR introduces shared TAP subnet/resource-sharing behavior (shared_subnet) in addition to the virtio device selection described in the PR title/description. Please update the PR description to explicitly cover this new behavior (or split it into a separate PR) so reviewers can evaluate scope and risk appropriately.
class OpenVmmNetworkSchema:
mode: str = OPENVMM_NETWORK_MODE_USER
device: str = OPENVMM_NETWORK_DEVICE_SYNTHETIC
shared_subnet: bool = False
connection_mode: str = OPENVMM_CONNECTION_MODE_FORWARDED_PORT
AI Test Case SelectionSelected 1 test case(s): smoke_test Marketplace image: Result: Succeeded |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Suppressed comments (3)
selftests/test_openvmm_node.py:177
- With schema defaults,
queue_countis omitted (None) unless explicitly configured. This assertion should match the default behavior for synthetic networking.
self.assertEqual(1, launch_config.network_queue_count)
lisa/sut_orchestrator/openvmm/node.py:2133
- When
shared_subnetsetup fails after iptables rules/dnsmasq state is created but before it’s copied intoSharedTapNetworkContext,_teardown_tap_networkskips cleanup becauseshared_tap_network_keyis set. This can leak host iptables rules and/or a dnsmasq process on setup errors.
Consider making teardown remove per-node iptables rules/dnsmasq when the shared context hasn’t yet recorded them (e.g., shared_context.input_rules_added / shared_context.dnsmasq_pid_file are empty).
if not shared_network_key and node_context.tap_input_rules_added:
rules_to_remove = node_context.tap_input_rules_added
for rule in rules_to_remove:
self.host_node.execute(
f"iptables -D {rule} || true",
selftests/test_openvmm_node.py:145
- This test configures a synthetic NIC but sets
queue_count=1. In the real schema,queue_countdefaults toNone, and forcing a default of 1 here makes the test validate a behavior that users won’t actually get by default.
This issue also appears on line 177 of the same file.
queue_count=1,
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Suppressed comments (3)
lisa/sut_orchestrator/openvmm/node.py:755
- Major: vps_per_socket defaults to processor_count when unspecified, which forces --vps-per-socket to always be passed (changing the default OpenVMM command line for existing runbooks). If the intent is to keep existing behavior unless the runbook explicitly opts in, pass through runbook.vps_per_socket directly and let it remain None by default.
),
processors=processor_count,
vps_per_socket=(
runbook.vps_per_socket
if runbook.vps_per_socket is not None
else processor_count
),
smt=runbook.smt,
lisa/sut_orchestrator/openvmm/node.py:421
- Major: In create_effective_network(), the shared_subnet branch returns before validate_tap_interface_names() is called. Since tap_name is still suffixed per guest, shared_subnet can silently produce invalid interface names (e.g., exceeding max length or using invalid characters) without the usual validation/error context.
base_tap_host_cidr = effective_network.tap_host_cidr
effective_network.tap_name = _increment_name_suffix(
effective_network.tap_name, guest_index
)
if effective_network.shared_subnet:
if effective_network.address_mode == OPENVMM_ADDRESS_MODE_STATIC:
effective_network.guest_address = _increment_ip_address(
effective_network.guest_address,
effective_network.tap_host_cidr,
guest_index,
)
if effective_network.forward_ssh_port:
effective_network.forwarded_port += guest_index
if effective_network.forwarded_port > 65535:
raise LisaException(
"cannot derive OpenVMM forwarded SSH port from "
f"'{network.forwarded_port}' for guest index {guest_index}: "
"derived port exceeds 65535. Use a lower base forwarded_port."
)
return effective_network
lisa/tools/openvmm.py:168
- Major: _validate_processor_topology() doesn't validate the relationship between processors and vps_per_socket. As written, vps_per_socket can be greater than processors or not divide evenly into processors, which is likely to produce an invalid or surprising CPU topology at runtime.
def _validate_processor_topology(self, config: OpenVmmLaunchConfig) -> None:
if config.vps_per_socket is not None and config.vps_per_socket < 1:
raise LisaException(
"OpenVMM vps_per_socket must be at least 1. "
"Set it to the number of virtual processors in each socket."
)
if config.smt and config.smt not in [
OPENVMM_SMT_AUTO,
OPENVMM_SMT_FORCE,
OPENVMM_SMT_OFF,
]:
raise LisaException(
f"OpenVMM SMT mode '{config.smt}' is not supported. "
f"Use {OPENVMM_SMT_AUTO}, {OPENVMM_SMT_FORCE}, or "
f"{OPENVMM_SMT_OFF}."
)
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.
Suppressed comments (4)
lisa/sut_orchestrator/openvmm/schema.py:369
- Major:
OpenVmmGuestNodeSchema.__post_init__rejects an empty SMT value. Ifsmtis intended to be optional (empty meaning "use OpenVMM default"), gate the validation onself.smtbeing non-empty (mirrorsOpenVmmLaunchConfigvalidation).
if self.smt not in [OPENVMM_SMT_AUTO, OPENVMM_SMT_FORCE, OPENVMM_SMT_OFF]:
lisa/sut_orchestrator/openvmm/schema.py:317
- Major:
OpenVmmGuestNodeSchema.smtdefaults toOPENVMM_SMT_OFF, which means OpenVMM launches will always emit--smt offeven when the runbook doesn't specify SMT. To preserve existing OpenVMM defaults unless explicitly configured, make the schema default empty and rely on the tool layer to validate non-empty values.
This issue also appears on line 369 of the same file.
smt: str = OPENVMM_SMT_OFF
lisa/sut_orchestrator/openvmm/node.py:754
- Major:
launch()always forcesvps_per_sockettoprocessor_countwhen the runbook value is unset, which makes the generated OpenVMM command always include--vps-per-socketand changes default behavior. If the intent is to preserve existing defaults unless explicitly configured, pass throughrunbook.vps_per_socketas-is (None) and letOpenVmmLaunchConfigomit the flag.
vps_per_socket=(
runbook.vps_per_socket
if runbook.vps_per_socket is not None
else processor_count
),
lisa/sut_orchestrator/openvmm/schema.py:122
- Minor: This PR adds
shared_subnetsupport and shared TAP resource management, but the PR title/description focuses on virtio device selection. Please update the PR description (and/or title) to mention the shared-subnet feature and runner behavior change so reviewers understand the full scope and can validate appropriately.
shared_subnet: bool = False
d13aa5f to
d33826e
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Suppressed comments (4)
lisa/sut_orchestrator/openvmm/schema.py:369
- If smt is allowed to be unset/empty to preserve prior behavior, the schema validation should treat an empty value as “not specified” (similar to lisa.tools.openvmm.OpenVmm._validate_processor_topology). As written, an empty string would fail validation.
if self.smt not in [OPENVMM_SMT_AUTO, OPENVMM_SMT_FORCE, OPENVMM_SMT_OFF]:
lisa/sut_orchestrator/openvmm/node.py:894
- This PR is titled/described as adding virtio device support, but this change set also introduces shared_subnet TAP networking (including shared bridge lifecycle, dnsmasq reuse, and lease matching). Please update the PR description/title to reflect the additional feature scope, or consider splitting the shared_subnet work into a separate PR for easier review and rollback.
if network.shared_subnet:
lisa/sut_orchestrator/openvmm/schema.py:317
- Defaulting smt to "off" will cause LISA to always pass an explicit SMT setting to OpenVMM (via --smt), which is a behavioral change for existing runbooks that previously relied on OpenVMM’s default. If the intent is to preserve prior defaults, consider using an empty default (meaning “don’t pass --smt unless configured”).
This issue also appears on line 369 of the same file.
smt: str = OPENVMM_SMT_OFF
lisa/sut_orchestrator/openvmm/node.py:761
- vps_per_socket is being set to processor_count when the runbook leaves it unset. This forces every OpenVMM launch to pass --vps-per-socket, changing default CPU topology behavior even when users didn’t opt in. It’s safer to pass through runbook.vps_per_socket as-is (None) and let OpenVMM use its default unless explicitly configured.
This issue also appears on line 894 of the same file.
vps_per_socket=(
runbook.vps_per_socket
if runbook.vps_per_socket is not None
else processor_count
),
d33826e to
c97403f
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.
Suppressed comments (4)
lisa/tools/openvmm.py:184
- This new exception message would be more actionable if it listed the supported values, so users can correct their runbook/config quickly.
raise LisaException(
f"Unsupported OpenVMM network device: {config.network_device}"
)
selftests/test_openvmm_node.py:179
- The launch propagation test only asserts disk_device/network_device/network_queue_count, but the PR also added/propagated iommu, vps_per_socket, and smt into OpenVmmLaunchConfig. Adding assertions for these fields would prevent regressions in the newly introduced launch config wiring.
launch_config = openvmm.launch_vm.call_args.args[0]
self.assertEqual(OPENVMM_DISK_DEVICE_SCSI, launch_config.disk_device)
self.assertEqual(OPENVMM_NETWORK_DEVICE_SYNTHETIC, launch_config.network_device)
self.assertEqual(1, launch_config.network_queue_count)
lisa/tools/openvmm.py:177
- This new exception message doesn’t provide remediation guidance. Including the supported values (as is already done in the OpenVmm runbook schema validation) makes failures easier to diagnose and fix.
This issue also appears on line 182 of the same file.
raise LisaException(
f"Unsupported OpenVMM disk device: {config.disk_device}"
)
lisa/tools/openvmm.py:197
- This new exception message is missing actionable guidance. Listing the supported IOMMU values (none/intel-vtd/amd-iommu) would align it with the schema validation and improve debuggability.
raise LisaException(f"Unsupported OpenVMM IOMMU: {config.iommu}")
c97403f to
2db3d40
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.
Suppressed comments (3)
.github/workflows/continuous-integration-workflow.yml:73
- The PR description still contains the template placeholders (Description/Related Issue/Tests) and doesn’t document what was validated. Please fill in the description and test results so reviewers can confirm the behavior change safely.
- name: Install Nox
# argcomplete 3.7.1 evaluates PEP 604 unions at import time on Python 3.9.
run: pip install nox toml "argcomplete!=3.7.1; python_version < '3.10'"
lisa/sut_orchestrator/openvmm/node.py:761
vps_per_socketis treated as optional inOpenVmmLaunchConfig(only adds--vps-per-socketwhen not None), butlaunch()always sets it toprocessor_countwhen the runbook leaves it unset. That forces the CLI flag on every launch and may change OpenVMM’s default CPU topology behavior. Consider passing through the runbook value directly so the flag is only emitted when explicitly configured.
vps_per_socket=(
runbook.vps_per_socket
if runbook.vps_per_socket is not None
else processor_count
),
lisa/sut_orchestrator/openvmm/schema.py:320
OpenVmmGuestNodeSchemadefaultssmttooff, andlaunch()always forwardsrunbook.smt, soOpenVmm.build_command()will always emit--smt offeven when the runbook doesn’t specify SMT. If the intent is to preserve OpenVMM’s previous default behavior, consider makingsmtoptional (e.g. empty/None) and only validating/emitting it when explicitly set.
allow_none=True,
),
)
smt: str = OPENVMM_SMT_OFF
min_raw_disk_size_gb: int = field(
Add PCIe virtio-net and virtio-blk device support for OpenVMM guests. Expose virtual IOMMU, shared TAP networking, network queue count, and processor topology settings through the runbook schema and launch configuration. Validate incompatible settings and extend the OpenVMM tool, schema, and node selftests to cover the new behavior. Allow nullable topology and queue defaults to round-trip through guest template expansion, and make the schema regression test register the OpenVMM node type explicitly. Keep Python 3.9 CI bootstrap compatible by excluding argcomplete 3.7.1, which evaluates PEP 604 unions at import time.
2db3d40 to
50f38a7
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.
Suppressed comments (4)
lisa/tools/openvmm.py:197
- Error message for an unsupported IOMMU value doesn’t list the allowed options. Include the supported constants so users know how to fix the configuration.
raise LisaException(f"Unsupported OpenVMM IOMMU: {config.iommu}")
lisa/tools/openvmm.py:184
- Error message for an unsupported network_device doesn’t list the allowed values, which makes misconfiguration harder to resolve. Include the supported device constants in the exception message.
raise LisaException(
f"Unsupported OpenVMM network device: {config.network_device}"
)
lisa/tools/openvmm.py:177
- Error message for an unsupported disk_device doesn’t list the allowed values, which makes misconfiguration harder to diagnose. Include the supported device constants in the exception message.
This issue also appears in the following locations of the same file:
- line 182
- line 197
raise LisaException(
f"Unsupported OpenVMM disk device: {config.disk_device}"
)
lisa/sut_orchestrator/openvmm/schema.py:123
- PR title/description focuses on virtio device selection, but this change also introduces additional OpenVMM runbook surface area (e.g., shared_subnet networking and CPU topology fields like vps_per_socket/smt). Please update the PR description/title to reflect the full scope, or split the unrelated behavior into a separate PR for easier review and rollback.
class OpenVmmNetworkSchema:
mode: str = OPENVMM_NETWORK_MODE_USER
device: str = OPENVMM_NETWORK_DEVICE_SYNTHETIC
queue_count: Optional[int] = field(
default=None,
metadata=schema.field_metadata(
field_function=schema.fields.Int,
validate=schema.validate.Range(min=1, max=65535),
allow_none=True,
),
)
shared_subnet: bool = False
AI Test Case SelectionSelected 1 test case(s): smoke_test Marketplace image: Result: Succeeded |
|
LiliDeng please check this. |
Allow OpenVMM runbooks to select virtio-blk disks and virtio-net NICs over PCIe while retaining existing synthetic defaults. Add command, schema, and launch propagation tests.
Description
Related Issue
Type of Change
Checklist
Test Validation
Key Test Cases:
Impacted LISA Features:
Tested Azure Marketplace Images:
Test Results